/*
 * Copyright 2017 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include <stdio.h>
#include <stdlib.h>

#include "fsl_common.h"
#include "board.h"
#include "fsl_lptmr.h"

#include "lwip/netif.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
#include "lwip/init.h"
#include "lwip/timers.h"
#include "netif/etharp.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/
extern uint8_t enc28j60_mac_addr[6]; /* 在ethernetif.c文件中已经定义过. */
struct netif enc28j60_netif; /* 定义一个全局使用的网卡对象. */

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
extern err_t ethernetif_init(struct netif *netif); /* 在ethernetif.c文件中已经定义. */
extern int ethernetif_input(struct netif *netif);
static void process_mac(void);

static void lptmr_init(void);

/*******************************************************************************
 * Code
 ******************************************************************************/

int main(void)
{
    board_init();
    printf("\r\n lwip_basic, build on %s, %s\r\n", __DATE__, __TIME__);

    /* leds. */
    led_init();
    led_on(1u << 0u);

    /* lptmr for led blinky. */
    lptmr_init();
    LPTMR_StartTimer(LPTMR0);

    /* lwip. */
    struct ip_addr ipaddr;
    struct ip_addr netmask;
    struct ip_addr gateway;

    /* 初始化lwip的内核. */
    lwip_init();
    IP4_ADDR(&gateway, 192, 168,   1,   1);
    IP4_ADDR(&netmask, 255, 255, 255,   0);
    IP4_ADDR(&ipaddr , 192, 168,   1, 131); /* 本机ip地址. */

    /* 向lwip注册网卡. */
    netif_add(&enc28j60_netif, &ipaddr, &netmask, &gateway,
              NULL, ethernetif_init, ethernet_input);
    netif_set_default(&enc28j60_netif); /* 设置enc28j60_netif为默认网卡. */
    netif_set_up(&enc28j60_netif); /* 启动enc28j60_netif网卡. */

    printf(" network ready.\r\n");
    printf(" - gateway: 192, 168,   1,   1\r\n");
    printf(" - netmask: 255, 255, 255,   0\r\n");
    printf(" - ip addr: 192, 168,   1, 131\r\n");
    printf("\r\n");


    /* 轮询方式查看网卡收到的帧, 并及时处理. */
    while (1)
    {
        /* 处理网卡收到的帧. */
        process_mac();

        /* 处理超时事件. */
        sys_check_timeouts();

        /* 用户代码. */
    }
}

/* 读完当前网卡接收到的mac帧数据, 并将输入送入lwip内核进行处理. */
static void process_mac(void)
{
    int ret = 0u;
    do
    {
        ret = ethernetif_input(&enc28j60_netif);
    } while (ret);
}

/* lptmr. */
static void lptmr_init(void)
{
    lptmr_config_t lptmr_config;

    LPTMR_GetDefaultConfig(&lptmr_config); /* using kCLOCK_LpoClk (1khz) as clock source. */
    LPTMR_Init(LPTMR0, &lptmr_config);

    LPTMR_SetTimerPeriod(LPTMR0, MSEC_TO_COUNT(100, CLOCK_GetFreq(kCLOCK_LpoClk))); /* 中断周期为100ms. */

    /* enable interrupt. */
    LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
    NVIC_EnableIRQ(LPTMR0_IRQn);
}

/* ISR for lptmr0. */
void LPTMR0_IRQHandler(void)
{
    LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);

    led_toggle( (1u << LED_NUM) -1u);
}

/* EOF. */

